package com.wyh.service.serviceImpl.appservieripml;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wyh.common.exception.BillNotFoundException;
import com.wyh.common.exception.ResourceNotFoundException;
import com.wyh.common.utils.SubStringFourUtils;
import com.wyh.domain.dto.groupfour.myproprietorDTO.PaymentRecordsDTO;
import com.wyh.domain.vo.gruopfour.myProprietorVO.*;

import com.wyh.domain.vo.gruopfour.threemeterVO.PageResult;
import com.wyh.mapper.appmapper.ChargeMapper;
import com.wyh.mapper.appmapper.MyProprietorMapper;
import com.wyh.service.appservice.IMyProprietorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.wyh.common.enums.MyProprietorEnum.*;
import static com.wyh.common.enums.ResultCodeEnum.SYSTEM_ERROR;

@Service
@Slf4j
public class MyProprietorServiceImpl implements IMyProprietorService {




    @Autowired
    private MyProprietorMapper myProprietorMapper;

    @Autowired
    private ChargeMapper chargeMapper;

    /**
     * 客户基本信息
     * @param id
     * @return
     */
    @Override
    public BasicInformation getBasicInformation(Integer id) {
        BasicInformation information = myProprietorMapper.getBasicInformation(id);
        if(information == null){
            throw new ResourceNotFoundException(SYSTEM_ERROR.getCode(),"客户基本信息不存在");
        }
        List<ContactsSummary> contacts = myProprietorMapper.getContacts(String.valueOf(id));
        information.setContacts(contacts);
        return information;
    }

    /**
     * 客户资源信息
     * @param id
     * @return
     */
    @Override
    public List<ResourceInformationVO> getResourceInformation(Integer id) {

        List<ResourceInformationVO> resourceInformation = myProprietorMapper.getResourceInformation(id);

        // 使用Map来合并并累加totalArrears
        Map<Integer, ResourceInformationVO> groupedResources = new HashMap<>();
        for (ResourceInformationVO info : resourceInformation) {
            if (groupedResources.containsKey(info.getResourceId())) {
                // 如果资源ID已存在，累加totalArrears
                ResourceInformationVO existingInfo = groupedResources.get(info.getResourceId());
                existingInfo.setTotalArrears(existingInfo.getTotalArrears() + info.getTotalArrears());
            } else {
                // 否则，将新对象放入Map中
                groupedResources.put(info.getResourceId(), info);
            }
        }
        // 将Map的值转换回列表，并覆盖原有的resourceInformation
        resourceInformation = new ArrayList<>(groupedResources.values());

        // 遍历集合并处理每个resourceName
        for (ResourceInformationVO resourceInfo : resourceInformation) {
            // 提取倒数第四个"/"之后的内容
            String s = SubStringFourUtils.subStringAfterNthSlashFromEnd(resourceInfo.getResourceName(), 4,'/');
            resourceInfo.setResourceName(s);
        }

        log.info("Updated resourceInformation: {}", resourceInformation);

        return resourceInformation;
    }

    /**
     * 缴费记录
     * @return
     */
    @Override
    public PageResult<PaymentRecordsVO> getPaymentRecords(PaymentRecordsDTO paymentRecordsDTO, List<Integer> ids) {
        PageHelper.startPage(paymentRecordsDTO.getPageNum(), paymentRecordsDTO.getPageSize());

        Page<PaymentRecordsVO> page = (Page<PaymentRecordsVO>) myProprietorMapper.getPaymentRecords(
                paymentRecordsDTO.getStartTime(),
                paymentRecordsDTO.getEndTime(),
                paymentRecordsDTO.getCustomerName(),
                paymentRecordsDTO.getPayee(),
                ids
        );

        return new PageResult<>(page.getTotal(), page.getResult());

    }

    /**
     * 获取我的业主
     * @param customerName
     * @param telephone
     * @param ids
     * @return
     */
    @Override
    public PageResult<MyProprietorVO> getMyProprietor(String customerName, String telephone, List<Integer> ids, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Page<MyProprietorVO> page= (Page<MyProprietorVO>) myProprietorMapper.getMyProprietor(customerName,telephone,ids);
        List<MyProprietorVO> filteredResult = page.getResult().stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return new PageResult((long) filteredResult.size(), filteredResult);
    }

    /**
     *  账单详情
     * @param id
     * @return
     */
    @Override
    public BillDetailVO getBillDetails(Integer id) {
        log.info("billId:{}",id);
        if (id == null){
            throw new BillNotFoundException(SYSTEM_ERROR.getCode(), "账单详情未找到");
        }
        List<ChargeDetailsVO> chargeDetails = myProprietorMapper.getChargeDetails(id);
        for (ChargeDetailsVO chargeDetail : chargeDetails){
            chargeDetail.setTimeRange(new TimeRange(chargeDetail.getStartTime(), chargeDetail.getEndTime()));
        }
        BillDetailVO billDetails = myProprietorMapper.getBillDetails(id);
        if (billDetails == null || chargeDetails.size() == 0){
            throw new BillNotFoundException(SYSTEM_ERROR.getCode(), "账单详情未找到");
        }
        billDetails.setChargeDetails(chargeDetails);
        return billDetails;



    }

    /**
     * 保证金余额
     * @param id
     * @return
     */
    @Override
    public List<DepositVO> getDeposit(Integer id) {
        if (id == null){
            throw new ResourceNotFoundException(SYSTEM_ERROR.getCode(), "该客户没有保证金");
        }
        List<DepositVO> allDeposits = myProprietorMapper.getDeposit(id);
        log.info("原始保证金余额: {}", allDeposits);

        if (allDeposits.isEmpty()) {
            return Collections.emptyList();
        }

        // 按depositName分组并获取每个分组中operationTime最新的记录
        List<DepositVO> latestDeposits = allDeposits.stream()
                .filter(deposit -> deposit.getDepositName() != null) // 过滤掉depositName为null的记录
                .collect(Collectors.groupingBy(DepositVO::getDepositName))
                .values().stream()
                .map(deposits -> {
                    Optional<DepositVO> latest = deposits.stream()
                            .max(Comparator.comparing(DepositVO::getOperationTime));
                    return latest.<IllegalStateException>orElseThrow(() -> new IllegalStateException("找不到最新的记录"));
                })
                .collect(Collectors.toList());

        log.info("处理后的保证金余额: {}", latestDeposits);
        return latestDeposits;

    }

    /**
     * 专用余额
     * @param id
     * @return
     */
    @Override
    public List<SpecialBalanceVO> getSpecialBalance(Integer id) {
    if (id == null) {
        throw new ResourceNotFoundException(SYSTEM_ERROR.getCode(), "该客户没有专用余额");
    }

    List<SpecialBalanceVO> specialBalance = myProprietorMapper.getSpecialBalance(id);

    // 分组并获取每组的第一条记录
    Map<Integer, SpecialBalanceVO> firstEntries = specialBalance.stream()
            .collect(Collectors.toMap(SpecialBalanceVO::getType, Function.identity(), (vo1, vo2) -> vo1));


    // 添加通用余额和水电气余额
    List<SpecialBalanceVO> result = firstEntries.values().stream()
            .filter(vo -> Objects.equals(vo.getType(), GENERAL_BALANCE.getCode()))
            .map(vo -> new SpecialBalanceVO(GENERAL_BALANCE.getCode(), vo.getBalance(), null)).collect(Collectors.toList());

    // 计算水电气总余额
    double waterElectricityGasBalance = firstEntries.values().stream()
            .filter(vo -> Objects.equals(vo.getType(), WATER_BALANCE.getCode()) ||
                    Objects.equals(vo.getType(), ELECTRICITY_BALANCE.getCode()) ||
                    Objects.equals(vo.getType(), GAS_BALANCE.getCode()))
            .mapToDouble(SpecialBalanceVO::getBalance)
            .sum();

    // 添加水电气余额汇总项
    result.add(new SpecialBalanceVO(SPECIAL_BALANCE.getCode(), waterElectricityGasBalance, null));

    // 确保至少有一项记录，如果没有通用余额，则添加一个零余额的特殊记录
    if (result.stream().noneMatch(vo -> Objects.equals(vo.getType(), GENERAL_BALANCE.getCode()))) {
        result.add(new SpecialBalanceVO(GENERAL_BALANCE.getCode(), 0D, null));
    }

    return result;
}


    /**
     * 变更资源
     * @param id
     * @return
     */
    @Override
    public ChangeResourceVO getChangeResource(Integer id) {
        if (id == null){
            throw new ResourceNotFoundException(SYSTEM_ERROR.getCode(), "资源未发现");
        }
        ChangeResourceVO changeResource = myProprietorMapper.getChangeResource(id);
        if(changeResource == null){
            throw new ResourceNotFoundException(SYSTEM_ERROR.getCode(), "资源未发现");
        }
        String s = SubStringFourUtils.subStringAfterNthSlashFromEnd(changeResource.getResourceName(), 4,'/');
        changeResource.setResourceName(s);
        return changeResource;
    }

    /**
     * 最近一年账单列表
     * @param id
     * @return
     */
    @Override
    public List<BillListVO> getBillList(Integer id) {
    if (id == null) {
        throw new ResourceNotFoundException(SYSTEM_ERROR.getCode(), "该客户没有账单");
    }

    List<BillListVO> billList = myProprietorMapper.getBillList(id);
    for (BillListVO bill : billList) {
        double totalArrears = bill.getTotalArrears();
        boolean isZero = Math.abs(totalArrears) < 1e-9; // 使用更精确的浮点数比较

        if (bill.getArrears() + bill.getLogged() == totalArrears) {
            bill.setPaymentStatus(UNPAID.getCode()); // 未结清
        } else if (isZero) {
            bill.setPaymentStatus(PAID.getCode()); // 已结清
        } else {
            bill.setPaymentStatus(PARTIALLY_PAID.getCode()); // 部分结清
        }
    }
    return billList;
}



}
